home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / SM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  2.6 KB  |  113 lines

  1. #include "stdlib.h"
  2. #include "math.h"
  3. #include <GL/glut.h>
  4. #include "sm.h"
  5.  
  6. #ifdef _WIN32
  7. #define drand48() ((double)rand()/RAND_MAX)
  8. #define srand48(x) (srand((x)))
  9. #endif
  10.  
  11. #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
  12. #define glBindTexture    glBindTextureEXT
  13. #endif
  14.  
  15. typedef struct elem {
  16.     float x, y, z;    /* current position */
  17.     float dx, dy, dz;    /* displacement */
  18.     float size;        /* scale factor */
  19.     float ts;        /* time stamp */
  20.     float opacity;    /* alpha value */
  21. } elem_t;
  22.  
  23. typedef struct smoke {
  24.     float ox, oy, oz;    /* origin */
  25.     float dx, dy, dz;    /* drift */
  26.     int elems;
  27.     float intensity;
  28.     float min_size;
  29.     float max_size;
  30.     unsigned texture;
  31.     elem_t *elem;
  32. } smoke_t;
  33.  
  34. void *
  35. new_smoke(float x, float y, float z, float dx, float dy, float dz,
  36.     int elems, float intensity, unsigned texture) {
  37.     int i;
  38.     smoke_t *s = malloc(sizeof(smoke_t));
  39.  
  40.     s->ox = x; s->oy = y, s->oz = z;
  41.     s->dx = dx; s->dy = dy; s->dz = dz;
  42.     s->min_size = .1f;
  43.     s->max_size = 1.0;
  44.     s->elems = elems;
  45.     s->elem = malloc(sizeof(elem_t)*elems);
  46.     for(i = 0; i < elems; i++) {
  47.     s->elem[i].ts = (float)i/elems;;
  48.     s->elem[i].dx = -drand48()*1.5f;
  49.     s->elem[i].dy = drand48()*1.5f;
  50.     s->elem[i].dz = drand48()*1.5f;
  51.     }
  52.     s->intensity = intensity;
  53.     s->texture = texture;
  54.     return s;
  55. }
  56.  
  57. void
  58. delete_smoke(void *smoke) {
  59.     smoke_t *s = smoke;
  60.     free(s->elem);
  61.     free(s);
  62. }
  63.  
  64. void
  65. draw_smoke(void *smoke) {
  66.     smoke_t *s = smoke;
  67.     int i;
  68.  
  69.     glEnable(GL_BLEND);
  70.     glDepthMask(0);
  71. #if 1
  72.     glEnable(GL_TEXTURE_2D);
  73. #else
  74.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  75. #endif
  76.     glBindTexture(GL_TEXTURE_2D, s->texture);
  77.     for(i = 0; i < s->elems; i++) {
  78.     elem_t *e = s->elem+i;
  79.     glPushMatrix();
  80.     glTranslatef(e->x, e->y, e->z);
  81.     glScalef(e->size, e->size, 1.);
  82.     glColor4f(s->intensity,s->intensity,s->intensity,e->opacity);
  83.     glBegin(GL_QUADS);
  84.     glTexCoord2f(0, 0); glVertex3f(-1., -1., -0.);
  85.     glTexCoord2f(0, 1); glVertex3f(-1., 1.,  0.);
  86.     glTexCoord2f(1, 1); glVertex3f( 1., 1.,  0.);
  87.     glTexCoord2f(1, 0); glVertex3f( 1., -1., -0.);
  88.     glEnd();
  89.     glPopMatrix();
  90.     }
  91.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  92.     glDisable(GL_TEXTURE_2D);
  93.     glDepthMask(1);
  94.     glDisable(GL_BLEND);
  95. }
  96.  
  97. void
  98. update_smoke(void *smoke, float tick) {
  99.     smoke_t *s = smoke;
  100.     int i;
  101.  
  102.     for(i = 0; i < s->elems; i++) {
  103.     elem_t *e = s->elem+i;
  104.     e->ts += tick;
  105.     if (e->ts > 1.0) e->ts = 0;
  106.     e->x = s->ox + s->dx*e->ts + e->dx*e->ts;
  107.     e->y = s->oy + s->dy*e->ts + e->dy*e->ts;
  108.     e->z = s->oz + s->dz*e->ts + e->dz*e->ts;
  109.     e->size = s->min_size + e->ts*s->max_size;
  110.     e->opacity = (1.0-e->ts);
  111.     }
  112. }
  113.